<script lang="ts">
export default {
  name: 'ListTree',
};
</script>
<template>
  <t-card class="card">
    <t-row align="stretch">
      <t-col :span="2">
        <t-tree expand-all activable hover :data="treeData" :keys="{ label: 'catname' }" @active="onTree" />
      </t-col>
      <t-col :span="10" class="border">
        <!-- 单页 -->
        <template v-if="curCat?.siteModel?.mark === 'page'">
          <t-row align="center" justify="space-between" class="card-header">
            <t-col>{{ curCat.catname }}</t-col>
            <t-col>
              <t-button theme="primary" @click="onPageFormSave">{{ t('common.save') }}</t-button>
            </t-col>
          </t-row>

          <page-form ref="pageFormRef" @save="onPageFormSave"></page-form>
        </template>

        <!-- 文章 -->
        <template v-if="['article', 'link'].includes(curCat?.siteModel?.mark)">
          <t-space direction="vertical">
            <t-row align="center" justify="space-between" class="card-header">
              <t-col>{{ curCat.catname }}</t-col>
              <t-col>
                <t-button
                  v-auth="['content:document:create']"
                  :disabled="curCat.children.length > 0"
                  theme="primary"
                  :content="t('common.add')"
                  @click="dialogFn.articleDialogShow"
                ></t-button>
              </t-col>
            </t-row>

            <common-search-bar :data="searchBarData" @search="tableFn.search" @reset="tableFn.reset" />

            <t-table
              row-key="id"
              :data="list"
              :columns="columns"
              :loading="isLoading"
              :pagination="pagination"
              header-affixed-top
              bordered
              stripe
              @page-change="tableFn.onPageChange"
            />
          </t-space>
        </template>
      </t-col>
    </t-row>

    <!-- 文章类型 弹窗表单 -->
    <article-form ref="articleDialogRef" @confirm="dialogFn.articleDialogConfirm"></article-form>

    <!-- 链接类型 弹窗表单 -->
    <link-form ref="linkDialogRef" @confirm="dialogFn.linkFormConfirm"></link-form>
  </t-card>
</template>

<script setup lang="ts">
import { EventType } from 'mitt';
import type { TableRowData, TreeProps } from 'tdesign-vue-next';
import { onMounted, ref } from 'vue';

import $api from '@/api';
import CommonSearchBar from '@/components/common-search-bar/index.vue';
import { $confirm, isLoading, useCommon } from '@/hooks/common';
import { t } from '@/locales';
import { mitter } from '@/utils/mitt';

import ArticleForm from './components/ArticleForm.vue';
import LinkForm from './components/LinkForm.vue';
import PageForm from './components/PageForm.vue';
import { ARTICLE_COLUMNS, LINK_COLUMNS, SEARCH_BAR_DATA } from './constants';

const treeData = ref([]);
const curCat = ref();
const pageFormRef = ref();
const linkDialogRef = ref();

const API = $api.content.document;
const searchBarData = ref([...SEARCH_BAR_DATA]);
const columns = ref();
const { list, pagination, ...commonIns }: Recordable = useCommon({ API });

const condition = ref({});
const articleDialogRef = ref();

const tableFn = {
  ...commonIns.tableFn,
  search(data: any) {
    pagination.value.current = 1;
    condition.value = data;
    getListContent();
  },
  reset() {
    pagination.value.current = 1;
    condition.value = {};
    getListContent();
  },
  async edit(row: TableRowData) {
    const res = await API.detail(row.id);
    // articleDialogRef.value.dialogShow('edit', res);
    if (curCat.value.siteModel.mark === 'article') {
      articleDialogRef.value.dialogShow('edit', res);
    } else if (curCat.value.siteModel.mark === 'link') {
      linkDialogRef.value.dialogShow('edit', res);
    }
  },
  async delete(row: TableRowData) {
    // 弹出确认删除的对话框
    $confirm({ theme: 'danger', body: t('common.deleteConfirm') }, async () => {
      await API.del(row.id);
      getListContent();
    });
  },
};
const dialogFn = {
  ...commonIns.dialogFn,
  articleDialogShow() {
    if (curCat.value.siteModel.mark === 'article') {
      articleDialogRef.value.dialogShow('add');
    } else if (curCat.value.siteModel.mark === 'link') {
      linkDialogRef.value.dialogShow('add');
    }
  },
  async articleDialogConfirm(type: string, data: Recordable) {
    console.log(type, data);
    const method = type === 'add' ? 'add' : 'update';
    data.category = curCat.value.id;
    try {
      await API[method](data);
      articleDialogRef.value.dialogHide();
      pagination.value.current = 1;
      getListContent();
    } catch (error) {
      articleDialogRef.value.loadingClear();
    }
  },
  async linkFormConfirm(type: string, data: Recordable) {
    console.log(type, data);
    const method = type === 'add' ? 'add' : 'update';
    data.category = curCat.value.id;
    try {
      await API[method](data);
      linkDialogRef.value.dialogHide();
      pagination.value.current = 1;
      getListContent();
    } catch (error) {
      linkDialogRef.value.loadingClear();
    }
  },
};

const getCategory = async () => {
  treeData.value = await $api.site.category.list();
  const data = treeData.value[0];

  curCat.value = data;
  if (data.siteModel.mark === 'page') {
    getPageContent();
  } else {
    getListContent();
  }
};
// 获取单页内容
const getPageContent = async () => {
  const { id, siteModel } = curCat.value;
  const params = {
    catId: id,
    modelMark: siteModel.mark,
  };
  const data = await API.list(params);

  pageFormRef.value.setData(data);
};

// 获取列表内容
const getListContent = async () => {
  // 标记加载状态为true
  isLoading.value = true;

  const { id, siteModel } = curCat.value;
  // 获取当前页码和每页大小
  const { current, pageSize } = pagination.value;
  const params = {
    catId: id,
    modelMark: siteModel.mark,
  };
  const query = {
    page: current,
    limit: pageSize,
  };

  // 调用API获取列表数据
  const res = await API.list(params, Object.assign(query, condition.value));

  const items = res?.items || [];

  // 如果当前页没有数据且页码大于1，回退一页并重新获取数据
  if (!items.length && pagination.value.current > 1) {
    pagination.value.current -= 1;
    getListContent();
  }

  // 格式化数据项，并更新列表数据
  list.value = items;

  // 更新总页数
  pagination.value.total = res.meta.totalItems;

  // 标记加载状态为false
  isLoading.value = false;
};

const onTree: TreeProps['onActive'] = (value, context) => {
  curCat.value = context.node.data;
  const { mark } = context.node.data.siteModel;
  if (mark === 'page') {
    getPageContent();
  } else {
    if (mark === 'article') {
      columns.value = ARTICLE_COLUMNS;
    }
    if (mark === 'link') {
      columns.value = LINK_COLUMNS;
    }

    getListContent();
  }
};

const onPageFormSave = () => {
  const data = pageFormRef.value.getData();
  data.category = data.category.id;
  API.update(data);
};

onMounted(() => {
  getCategory();
});

// 监听mitter事件，并根据事件类型执行相应的操作
mitter.on('*', (type: EventType, row: TableRowData) => {
  const fnMap: Recordable = {
    edit: () => {
      tableFn.edit(row);
    },
    delete: () => {
      tableFn.delete(row);
    },
    display: () => {
      tableFn.display(row, 1 - row.display);
    },
    displayed: async () => {
      row.display = 1 - row.display;
      getListContent();
    },
  };
  if (fnMap[type.toString()]) {
    fnMap[type.toString()]();
  } else {
    console.log(type, '没有监听逻辑');
  }
});
</script>

<style lang="less" scoped>
.card :deep(.t-card__body) {
  padding: 0;
}
.t-col {
  padding: 20px !important;
}
.border {
  border-left: 1px solid var(--td-border-level-1-color);
}
.card-header {
  margin: -20px -20px 20px !important;
  border-bottom: 1px solid var(--td-border-level-1-color);
}
</style>
